import RandomUtil from "../utils/RandomUtil"
import Player, { IPlayerVo, PlayerVo } from "./Player"
import Referee from "./Referee"
// import Referee from "./Referee"
import { User } from "./User"

/**
 * 房间数据对象接口
 */
export interface IRoomVo {
  id: string
  players: Array<IPlayerVo | undefined>
  maxOfPeople: number
}

export class RoomVo implements IRoomVo {
  id: string
  players: (IPlayerVo | undefined)[]
  maxOfPeople: number

  constructor(room: IRoomVo) {
    this.id = room.id
    this.players = []
    room.players.forEach(player => {
      if (player) {
        this.players.push(new PlayerVo(player))
      } else {
        this.players.push(undefined)
      }
    })
    this.maxOfPeople = room.maxOfPeople
  }
}

/**
 * 房间对象
 */
export default class Room implements IRoomVo {
  private _id: string = ''                              // 房间id
  public players: Array<Player | undefined> = []                    // 房间人员
  public maxOfPeople: number = 0                        // 房间最大人数
  public referee: Referee                               // 裁判

  constructor(maxofPeople: number) {
    //this._id = this.getRandomId()   // 生成房间号
    this._id = 'room-1683266477176-22520'   // test
    this.maxOfPeople = maxofPeople
    this.players = new Array<Player>(3)                    // 房间人员
    console.log('init room this.players:', this.players)
    this.referee = new Referee(this.players)
  }

  public get id(): string {
    return this._id
  }

  /**
   * 获取随机房间号
   * @returns 
   */
  private getRandomId(): string {
    return `room-${Date.now()}-${RandomUtil.getRangeInt(10000, 99999)}`
  }

  /**
   * 房间是否满
   * @returns 
   */
  public isFull(): boolean {
    let emptyCount = 0
    this.players.forEach(player => {
      if (player === undefined) {
        emptyCount++
      }
    })
    return emptyCount >= this.maxOfPeople
  }

  /***
   * 房间是否为空
   */
  public isEmpty(): boolean {
    let emptyCount = 0
    this.players.forEach(player => {
      if (player === undefined) {
        emptyCount++
      }
    })
    return emptyCount == 0
  }

  /**
   * 获得一个空位置
   */
  public getEmptyIndex(): number {
    for (let i = 0; i < this.players.length; i++) {
      if (this.players[i] === undefined) {
        return i
      }
    }

    return -1
  }

  /**
   * 加入房间
   * @param user 
   * @returns 座位号（下标）
   */
  public intoRoom(user: User): number {
    if (this.isFull()) {
      throw new Error('room is full')
    }

    const index = this.getEmptyIndex()
    this.players[index] = new Player(user)
    return index
  }

  /**
   * 离开房间
   * @param uid 
   */
  public leaveRoom(uid: string) {
    // 查找用户
    const playerIndex = this.findPlayerIndexById(uid)

    if (playerIndex === -1) {
      throw new Error(`[room] this user does not exist, user id = ${uid}`)
    }

    // 删除用户信息
    this.players[playerIndex] = undefined

    return playerIndex
  }

  /**
   * 这个用户id是否存在房间里
   * @param uid 
   */
  public hasPlayer(uid: string): boolean {
    const index = this.findPlayerIndexById(uid)
    if (index == -1) {
      return false
    }

    return true
  }

  /**
   * 根据用户id查找用户的座位
   * @param uid 
   * @returns 座位号
   */
  public findPlayerIndexById(uid: string): number {
    const index = this.players.findIndex(player => {
      return player != undefined && player.id === uid
    })
    return index
  }

  /**
   * 根据用户id获取玩家对象
   * @param uid 
   */
  public getPlayerByUserId(uid: string): Player | undefined {
    return this.players.find((player) => {
      if (player != undefined && player.id === uid) {
        return true
      }
    })
  }

  /**
   * 设置用户准备
   * @param uid
   */
  public setUserPrepare(uid: string, isPrepare: boolean) {
    const player = this.getPlayerByUserId(uid)

    if (player == undefined) {
      throw new Error(`[room] this user does not exist, user id = ${uid}`)
    }

    // 设为准备
    player.prepare = isPrepare
  }


  // public isPrepareByUserId(uid: string): boolean {
  //   const player = this.getPlayerByUserId(uid)

  //   if (player == undefined) {
  //     throw new Error(`[room] this user does not exist, user id = ${uid}`)
  //   }

  //   return player.prepare
  // }

  /**
   * 是否全部准备
   * @returns 
   */
  public isAllPrepare(): boolean {
    let prepareCount = 0
    this.players.forEach((player) => {
      if (player != undefined && player.isPrepare()) {
        prepareCount++
      }
    })

    return prepareCount == this.maxOfPeople
  }

  /**
   * 设置玩家已经整理好牌
   * @param uid 
   */
  public setPlayerReady(uid: string) {
    const player = this.getPlayerByUserId(uid)

    if (player == undefined) {
      throw new Error(`[room] this user does not exist, user id = ${uid}`)
    }

    // 设为准备
    player.ready = true
  }

  /**
   * 是否全部都整理好牌
   */
  public isAllReady(): boolean {
    let readyCount = 0
    this.players.forEach((player) => {
      if (player != undefined && player.isReady()) {
        readyCount++
      }
    })

    return readyCount == this.maxOfPeople
  }

  /**
   * 获取给前端发送的数据
   */
  public getVo(): RoomVo {
    return new RoomVo(this)
  }
}